"use strict";
cc._RF.push(module, '50eaawLPZRENJEcGEpVVJKs', 'PopupManager');
// eazax-ccc/core/PopupManager.ts

"use strict";
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
    function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
    return new (P || (P = Promise))(function (resolve, reject) {
        function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
        function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
        function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
        step((generator = generator.apply(thisArg, _arguments || [])).next());
    });
};
var __generator = (this && this.__generator) || function (thisArg, body) {
    var _ = { label: 0, sent: function() { if (t[0] & 1) throw t[1]; return t[1]; }, trys: [], ops: [] }, f, y, t, g;
    return g = { next: verb(0), "throw": verb(1), "return": verb(2) }, typeof Symbol === "function" && (g[Symbol.iterator] = function() { return this; }), g;
    function verb(n) { return function (v) { return step([n, v]); }; }
    function step(op) {
        if (f) throw new TypeError("Generator is already executing.");
        while (_) try {
            if (f = 1, y && (t = op[0] & 2 ? y["return"] : op[0] ? y["throw"] || ((t = y["return"]) && t.call(y), 0) : y.next) && !(t = t.call(y, op[1])).done) return t;
            if (y = 0, t) op = [op[0] & 2, t.value];
            switch (op[0]) {
                case 0: case 1: t = op; break;
                case 4: _.label++; return { value: op[1], done: false };
                case 5: _.label++; y = op[1]; op = [0]; continue;
                case 7: op = _.ops.pop(); _.trys.pop(); continue;
                default:
                    if (!(t = _.trys, t = t.length > 0 && t[t.length - 1]) && (op[0] === 6 || op[0] === 2)) { _ = 0; continue; }
                    if (op[0] === 3 && (!t || (op[1] > t[0] && op[1] < t[3]))) { _.label = op[1]; break; }
                    if (op[0] === 6 && _.label < t[1]) { _.label = t[1]; t = op; break; }
                    if (t && _.label < t[2]) { _.label = t[2]; _.ops.push(op); break; }
                    if (t[2]) _.ops.pop();
                    _.trys.pop(); continue;
            }
            op = body.call(thisArg, _);
        } catch (e) { op = [6, e]; y = 0; } finally { f = t = 0; }
        if (op[0] & 5) throw op[1]; return { value: op[0] ? op[1] : void 0, done: true };
    }
};
Object.defineProperty(exports, "__esModule", { value: true });
exports.PopupParams = exports.PopupShowResult = exports.PopupCacheMode = void 0;
var PopupBase_1 = require("../components/popups/PopupBase");
/** 弹窗缓存模式 */
var PopupCacheMode;
(function (PopupCacheMode) {
    /** 一次性的（立即销毁节点，预制体资源随即释放） */
    PopupCacheMode[PopupCacheMode["Once"] = 1] = "Once";
    /** 正常的（立即销毁节点，但是缓存预制体资源） */
    PopupCacheMode[PopupCacheMode["Normal"] = 2] = "Normal";
    /** 频繁的（只关闭节点，且缓存预制体资源） */
    PopupCacheMode[PopupCacheMode["Frequent"] = 3] = "Frequent";
})(PopupCacheMode = exports.PopupCacheMode || (exports.PopupCacheMode = {}));
/** 弹窗请求结果 */
var PopupShowResult;
(function (PopupShowResult) {
    /** 展示成功（已关闭） */
    PopupShowResult[PopupShowResult["Done"] = 1] = "Done";
    /** 展示失败（加载失败） */
    PopupShowResult[PopupShowResult["Failed"] = 2] = "Failed";
    /** 等待中（已加入等待队列） */
    PopupShowResult[PopupShowResult["Waiting"] = 3] = "Waiting";
})(PopupShowResult = exports.PopupShowResult || (exports.PopupShowResult = {}));
/**
 * 弹窗管理器
 * @see PopupManager.ts https://gitee.com/ifaswind/eazax-ccc/blob/master/core/PopupManager.ts
 * @see PopupBase.ts https://gitee.com/ifaswind/eazax-ccc/blob/master/components/popups/PopupBase.ts
 * @version 20210524
 */
var PopupManager = /** @class */ (function () {
    function PopupManager() {
    }
    Object.defineProperty(PopupManager, "prefabCache", {
        /** 预制体缓存 */
        get: function () { return this._prefabCache; },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PopupManager, "nodeCache", {
        /** 节点缓存 */
        get: function () { return this._nodeCache; },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PopupManager, "current", {
        /** 当前弹窗请求 */
        get: function () { return this._current; },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PopupManager, "queue", {
        /** 等待队列 */
        get: function () { return this._queue; },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PopupManager, "suspended", {
        /** 被挂起的弹窗队列 */
        get: function () { return this._suspended; },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PopupManager, "CacheMode", {
        /** 弹窗缓存模式 */
        get: function () { return PopupCacheMode; },
        enumerable: false,
        configurable: true
    });
    Object.defineProperty(PopupManager, "ShowResult", {
        /** 弹窗请求结果 */
        get: function () { return PopupShowResult; },
        enumerable: false,
        configurable: true
    });
    /**
     * 展示弹窗，如果当前已有弹窗在展示中则加入等待队列
     * @param path 弹窗预制体相对路径（如：prefabs/MyPopup）
     * @param options 弹窗选项（将传递给弹窗的组件）
     * @param params 弹窗展示参数
     * @example
     * const options = {
     *     title: 'Hello',
     *     content: 'This is a popup!'
     * };
     * const params = {
     *     mode: PopupCacheMode.Normal
     * };
     * PopupManager.show('prefabs/MyPopup', options, params);
     */
    PopupManager.show = function (path, options, params) {
        var _this = this;
        return new Promise(function (res) { return __awaiter(_this, void 0, void 0, function () {
            var node, prefab, popup, finishCallback;
            var _this = this;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        // 解析处理参数
                        params = this.parseParams(params);
                        if (!(this._current || this.locked)) return [3 /*break*/, 3];
                        if (!(params && params.immediately)) return [3 /*break*/, 2];
                        this.locked = false;
                        // 挂起当前弹窗
                        return [4 /*yield*/, this.suspend()];
                    case 1:
                        // 挂起当前弹窗
                        _a.sent();
                        return [3 /*break*/, 3];
                    case 2:
                        // 将请求推入等待队列
                        this.push(path, options, params);
                        res(PopupShowResult.Waiting);
                        return [2 /*return*/];
                    case 3:
                        // 保存为当前弹窗，阻止新的弹窗请求
                        this._current = {
                            path: path,
                            options: options,
                            params: params
                        };
                        node = this.getNodeFromCache(path);
                        if (!!cc.isValid(node)) return [3 /*break*/, 5];
                        // 开始回调
                        this.loadStartCallback && this.loadStartCallback();
                        return [4 /*yield*/, this.load(path)];
                    case 4:
                        prefab = _a.sent();
                        // 完成回调
                        this.loadFinishCallback && this.loadFinishCallback();
                        // 加载失败（一般是路径错误导致的）
                        if (!cc.isValid(prefab)) {
                            cc.warn('[PopupManager]', '弹窗加载失败', path);
                            this._current = null;
                            res(PopupShowResult.Failed);
                            return [2 /*return*/];
                        }
                        // 实例化节点
                        node = cc.instantiate(prefab);
                        _a.label = 5;
                    case 5:
                        popup = node.getComponent(PopupBase_1.default);
                        if (!popup) {
                            cc.warn('[PopupManager]', '未找到弹窗组件', path);
                            this._current = null;
                            res(PopupShowResult.Failed);
                            return [2 /*return*/];
                        }
                        // 保存组件引用
                        this._current.popup = popup;
                        // 保存节点引用
                        this._current.node = node;
                        // 添加到场景中
                        node.setParent(this.container || cc.Canvas.instance.node);
                        // 显示在最上层
                        node.setSiblingIndex(cc.macro.MAX_ZINDEX);
                        finishCallback = function (suspended) { return __awaiter(_this, void 0, void 0, function () {
                            var _this = this;
                            return __generator(this, function (_a) {
                                switch (_a.label) {
                                    case 0:
                                        if (suspended) {
                                            return [2 /*return*/];
                                        }
                                        // 是否需要锁定
                                        this.locked = (this._suspended.length > 0 || this._queue.length > 0);
                                        // 回收
                                        this.recycle(path, node, params.mode);
                                        this._current = null;
                                        res(PopupShowResult.Done);
                                        // 延迟一会儿
                                        return [4 /*yield*/, new Promise(function (_res) {
                                                cc.Canvas.instance.scheduleOnce(_res, _this.interval);
                                            })];
                                    case 1:
                                        // 延迟一会儿
                                        _a.sent();
                                        // 下一个弹窗
                                        this.next();
                                        return [2 /*return*/];
                                }
                            });
                        }); };
                        popup.setFinishCallback(finishCallback);
                        // 展示
                        popup.show(options);
                        return [2 /*return*/];
                }
            });
        }); });
    };
    /**
     * 隐藏当前弹窗
     */
    PopupManager.hide = function () {
        if (this._current.popup) {
            this._current.popup.hide();
        }
    };
    /**
     * 从缓存中获取节点
     * @param path 弹窗路径
     */
    PopupManager.getNodeFromCache = function (path) {
        // 从节点缓存中获取
        var nodeCache = this._nodeCache;
        if (nodeCache.has(path)) {
            var node = nodeCache.get(path);
            if (cc.isValid(node)) {
                return node;
            }
            // 删除无效引用
            nodeCache.delete(path);
        }
        // 从预制体缓存中获取
        var prefabCache = this._prefabCache;
        if (prefabCache.has(path)) {
            var prefab = prefabCache.get(path);
            if (cc.isValid(prefab)) {
                return cc.instantiate(prefab);
            }
            // 删除无效引用
            prefabCache.delete(path);
        }
        // 无
        return null;
    };
    /**
     * 展示挂起或等待队列中的下一个弹窗
     */
    PopupManager.next = function () {
        if (this._current ||
            (this._suspended.length === 0 && this._queue.length === 0)) {
            return;
        }
        // 取出一个请求
        var request = null;
        if (this._suspended.length > 0) {
            // 挂起队列
            request = this._suspended.shift();
        }
        else {
            // 等待队列
            request = this._queue.shift();
        }
        // 解除锁定
        this.locked = false;
        // 已有实例
        if (cc.isValid(request.popup)) {
            // 设为当前弹窗
            this._current = request;
            // 直接展示
            request.popup.show(request.options);
            return;
        }
        // 加载并展示
        this.show(request.path, request.options, request.params);
    };
    /**
     * 添加一个弹窗请求到等待队列中，如果当前没有展示中的弹窗则直接展示该弹窗。
     * @param path 弹窗预制体相对路径（如：prefabs/MyPopup）
     * @param options 弹窗选项
     * @param params 弹窗展示参数
     */
    PopupManager.push = function (path, options, params) {
        // 直接展示
        if (!this._current && !this.locked) {
            this.show(path, options, params);
            return;
        }
        // 加入队列
        this._queue.push({ path: path, options: options, params: params });
        // 按照优先级从小到大排序
        this._queue.sort(function (a, b) { return (a.params.priority - b.params.priority); });
    };
    /**
     * 挂起当前展示中的弹窗
     */
    PopupManager.suspend = function () {
        return __awaiter(this, void 0, void 0, function () {
            var request;
            return __generator(this, function (_a) {
                switch (_a.label) {
                    case 0:
                        if (!this._current) {
                            return [2 /*return*/];
                        }
                        request = this._current;
                        // 将当前弹窗推入挂起队列
                        this._suspended.push(request);
                        // 关闭当前弹窗（挂起）
                        return [4 /*yield*/, request.popup.hide(true)];
                    case 1:
                        // 关闭当前弹窗（挂起）
                        _a.sent();
                        // 置空当前
                        this._current = null;
                        return [2 /*return*/];
                }
            });
        });
    };
    /**
     * 回收弹窗
     * @param path 弹窗路径
     * @param node 弹窗节点
     * @param mode 缓存模式
     */
    PopupManager.recycle = function (path, node, mode) {
        switch (mode) {
            // 一次性
            case PopupCacheMode.Once:
                node.destroy();
                this._nodeCache.delete(path);
                this.release(path);
                break;
            // 正常
            case PopupCacheMode.Normal:
                node.destroy();
                this._nodeCache.delete(path);
                break;
            // 频繁
            case PopupCacheMode.Frequent:
                node.removeFromParent(false);
                this._nodeCache.set(path, node);
                break;
        }
    };
    /**
     * 加载并缓存弹窗预制体资源
     * @param path 弹窗路径
     */
    PopupManager.load = function (path) {
        var _this = this;
        return new Promise(function (res) {
            var prefabMap = _this._prefabCache;
            // 先看下缓存里有没有，避免重复加载
            if (prefabMap.has(path)) {
                var prefab = prefabMap.get(path);
                // 缓存是否有效
                if (cc.isValid(prefab)) {
                    res(prefab);
                    return;
                }
                else {
                    // 删除无效引用
                    prefabMap.delete(path);
                }
            }
            // 动态加载
            cc.resources.load(path, function (error, prefab) {
                if (error) {
                    res(null);
                    return;
                }
                // 缓存预制体
                prefabMap.set(path, prefab);
                // 增加引用计数
                prefab.addRef();
                res(prefab);
            });
        });
    };
    /**
     * 尝试释放弹窗资源（注意：弹窗内部动态加载的资源请自行释放）
     * @param path 弹窗路径
     */
    PopupManager.release = function (path) {
        // 移除节点
        var nodeCache = this._nodeCache;
        var node = nodeCache.get(path);
        if (node) {
            nodeCache.delete(path);
            if (cc.isValid(node)) {
                node.destroy();
            }
            node = null;
        }
        // 移除预制体
        var prefabCache = this._prefabCache;
        var prefab = prefabCache.get(path);
        if (prefab) {
            prefabCache.delete(path);
            prefab.decRef();
            prefab = null;
        }
    };
    /**
     * 解析参数
     * @param params 参数
     */
    PopupManager.parseParams = function (params) {
        if (params == undefined) {
            return new PopupParams();
        }
        // 是否为对象
        if (Object.prototype.toString.call(params) !== '[object Object]') {
            cc.warn('[PopupManager]', '弹窗参数无效，使用默认参数');
            return new PopupParams();
        }
        // 缓存模式
        if (params.mode == undefined) {
            params.mode = PopupCacheMode.Normal;
        }
        // 优先级
        if (params.priority == undefined) {
            params.priority = 0;
        }
        // 立刻展示
        if (params.immediately == undefined) {
            params.immediately = false;
        }
        return params;
    };
    PopupManager._prefabCache = new Map();
    PopupManager._nodeCache = new Map();
    PopupManager._current = null;
    PopupManager._queue = [];
    PopupManager._suspended = [];
    /** 锁定状态 */
    PopupManager.locked = false;
    /** 用于存放弹窗节点的容器节点（不设置则默认为当前 Canvas） */
    PopupManager.container = null;
    /** 连续展示弹窗的时间间隔（秒） */
    PopupManager.interval = 0.05;
    /**
     * 弹窗动态加载开始回调
     * @example
     * PopupManager.loadStartCallback = () => {
     *     LoadingTip.show();
     * };
     */
    PopupManager.loadStartCallback = null;
    /**
     * 弹窗动态加载结束回调
     * @example
     * PopupManager.loadFinishCallback = () => {
     *     LoadingTip.hide();
     * };
     */
    PopupManager.loadFinishCallback = null;
    return PopupManager;
}());
exports.default = PopupManager;
/** 弹窗展示参数 */
var PopupParams = /** @class */ (function () {
    function PopupParams() {
        /** 缓存模式 */
        this.mode = PopupCacheMode.Normal;
        /** 优先级（优先级大的优先展示） */
        this.priority = 0;
        /** 立刻展示（将会挂起当前展示中的弹窗） */
        this.immediately = false;
    }
    return PopupParams;
}());
exports.PopupParams = PopupParams;

cc._RF.pop();